package com.ctshk.rpc.payment.strategy;

import com.ctshk.rpc.payment.config.ApplicationContextProvider;
import com.ctshk.rpc.payment.dto.PayDetailsDTO;
import com.ctshk.rpc.payment.dto.RefundDetailsDTO;
import com.ctshk.rpc.payment.dto.req.PayRefundReq;
import com.ctshk.rpc.payment.enums.RefundStatus;
import com.ctshk.rpc.payment.req.PayCommonReq;
import org.springframework.util.Assert;

import java.util.Map;

/**
 * @BelongsProject: ctshk-cloud
 * @BelongsPackage: com.ctshk.rpc.payment.strategy
 * @Author: hef
 * @CreateTime: 2021-04-20 17:44
 * @Description: 描述
 */
public class PayContext {
    /**
     * 支付策略
     */
    private PayStrategy payStrategy;

    public PayContext(PayStrategy payStrategy) {
        this.payStrategy = payStrategy;
    }

    public Object pay(PayCommonReq req) throws Exception {
        return this.payStrategy.pay(req);
    }

    public Object payCallback(Map<String, String> paramMap, Long recordId) {
        return this.payStrategy.payCallbackTemplate(paramMap, recordId);
    }

    public PayDetailsDTO queryTransaction(String orderNumber) {
        return this.payStrategy.getPayDetails(orderNumber);
    }

    public RefundStatus refund(PayRefundReq req) {
        return this.payStrategy.refundTemplate(req);
    }

    public RefundDetailsDTO getRefundDetail(String orderNumber, String refundNumber) {
        return this.payStrategy.getRefundDetail(orderNumber, refundNumber);
    }

    public Object refundNotify(Map<String, String> paramMap){
        return this.payStrategy.refundNotify(paramMap);
    }

    public static Object pay(PayCommonReq req, Class<? extends PayStrategy> clazz) throws Exception {
        PayContext payContext = getPayContext(clazz);
        return payContext.pay(req);
    }

    public static Object callback(Map<String, String> paramMap, Long recordId, Class<? extends PayStrategy> clazz) {
        PayContext payContext = getPayContext(clazz);
        return payContext.payCallback(paramMap, recordId);
    }

    public static PayDetailsDTO queryTransaction(String orderNumber, Class<? extends PayStrategy> clazz) {
        PayContext payContext = getPayContext(clazz);
        return payContext.queryTransaction(orderNumber);
    }


    public static RefundStatus refund(PayRefundReq req, Class<? extends PayStrategy> clazz) {
        PayContext payContext = getPayContext(clazz);
        return payContext.refund(req);
    }

    public static RefundDetailsDTO getRefundDetail(String orderNumber, String refundNumber, Class<? extends PayStrategy> clazz) {
        PayContext payContext = getPayContext(clazz);
        return payContext.getRefundDetail(orderNumber, refundNumber);
    }

    public static Object refundNotify(Map<String, String> paramMap,Class<? extends PayStrategy> clazz){
        PayContext payContext = getPayContext(clazz);
        return payContext.refundNotify(paramMap);
    }


    private static PayContext getPayContext(Class<? extends PayStrategy> clazz) {
        PayStrategy bean = getStrategyBean(clazz);
        return new PayContext(bean);
    }

    private static PayStrategy getStrategyBean(Class<? extends PayStrategy> clazz) {
        Assert.notNull(clazz, "无法获取具体的付款策略");
        PayStrategy bean = ApplicationContextProvider.getBean(clazz);
        Assert.notNull(bean, "strategy cannot be empty");
        return bean;
    }
}
